<template>
  <div class="upload_table" ref="uploadtestRef">
    <el-upload
      v-model:file-list="fileList"
      :class="uploadClass"
      class="upload-file"
      action="#"
      :http-request="handleRequestInfo"
      drag
      :show-file-list="defaultShowList"
      :list-type="listType"
      :on-change="handleChange"
      :name="props?.postImage"
      :maxSize="props?.maxSize"
      :multiple="multiple"
      :limit="limit"
      :accept="accept"
      :before-upload="beforeAvatarUpload"
      :before-remove="beforeRemoveUpload"
    >
      <!-- :on-change="handleChange" -->
      <!-- //文件列表类型，text/picture/picture-card -->
      <!-- accept="image/jpg, image/jpeg, image/png" -->
      <template v-if="uploadClass == 'picUpload'">
        <div class="picUploadCont">
          <el-icon><Plus /></el-icon>
        </div>
      </template>
      <template v-else>
        <div>
          <el-icon class="el-icon--upload"><upload-filled /></el-icon>
          <!-- <el-icon class="el-icon--upload"><Upload /></el-icon> -->
          <div class="el-upload__text">
            {{ $t("merak.push_fil_tip") }} <em>{{ $t("merak.click_upload") }}</em>
            {{ tipMsgOther }}
          </div>
        </div>
      </template>

      <template #tip v-if="tipShow">
        <div class="el-upload__tip">
          {{ tipMsg }}
        </div>
      </template>
    </el-upload>

    <div v-if="fileListShow">
      <div class="th_tr">
        <div style="width: 40%" class="upload_th">{{ $t("merak.upload_file_name") }}</div>
        <div style="width: 20%" class="upload_th">{{ $t("merak.upload_file_type") }}</div>
        <div style="width: 20%" class="upload_th">{{ $t("merak.upload_file_status") }}</div>
        <div class="upload_th">
          {{ $t("merak.action") }}
        </div>
      </div>

      <div v-if="fileList.length < 1" style="padding: 100px 40px 100px; display: flex; justify-content: center">
        <img :src="EmptyPng" style="object-fit: cover; height: 130px" />
      </div>

      <div v-else class="file_ever" v-for="(item, index) in fileList">
        <div class="td" style="width: 40%">{{ item.name }}</div>
        <div class="td" style="width: 20%">{{ item.type }}</div>
        <div class="td icon_show" style="width: 20%">
          <span v-if="item.status == 'success'" class="success"
            ><el-icon><CircleCheck /></el-icon
          ></span>
          <div v-else class="error">
            <el-icon><CircleClose /></el-icon>
            <!-- <span v-if="item.response">  {{  item.tip }}</span> -->
            <span> {{ item.raw?.tip }}</span>
          </div>
        </div>
        <div class="td">
          <el-button type="danger" link @click="delfile(fileList, index)"> {{ $t("merak.delete") }} </el-button>
        </div>

        <div v-if="item.percentage" class="progress_div">
          <el-progress v-if="item.percentage < 100" :percentage="item.percentage" />
        </div>
      </div>
    </div>

    <!-- loading -->
    <el-dialog
      v-model="uploadLoadingObj.loadingVisable"
      modal-class="upload_loading"
      width="500"
      :show-close="uploadLoadingObj.uploadPercentage == 100"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :before-close="handleClose"
    >
      <!--  :show-close="uploadLoadingObj.uploadPercentage == 100" -->
      <div class="upload_module">
        <div v-if="uploadLoadingObj.uploadPercentage == 100">
          <el-result icon="success" title="上传完成"> </el-result>

          <div class="errTip" v-if="uploadLoadingObj.fileNum > 0 && failBoolShow">
            含有上传失败{{ uploadLoadingObj.fileNum }}条，请从失败页面查看
          </div>
        </div>
        <div v-else class="loading_block">
          <div class="loading_File" v-loading="true"></div>
          <div class="loading_tip" v-if="uploadLoadingObj.currUploadNum > 1">
            上传中，已完成<span class="success">{{ uploadLoadingObj.uplodingNum }}</span
            >/<span class="total">{{ uploadLoadingObj.currUploadNum }}</span>
          </div>
          <div class="loading_tip" v-else>上传中</div>
          <!-- <el-progress
            striped
            striped-flow
            :duration="20"
            :text-inside="true"
            :stroke-width="15"
            :percentage="uploadLoadingObj.uploadPercentage"
          >
            <span>{{ uploadLoadingObj.uplodingNum }}/{{ uploadLoadingObj.currUploadNum }}</span>
          </el-progress> -->
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, getCurrentInstance, onMounted, onUnmounted, computed, nextTick } from "vue";
import { ElMessage, Resolve } from "element-plus";
import { uploadFiles } from "@/api/modules/upload";
import EmptyPng from "@/assets/images/empty.png";
import {
  moreConfirm,
  confirmWarningMsg,
  successMsg,
  warnMsg,
  failMsg,
  confirmSuccessMsg,
  delConfimMsg
} from "@/utils/messageUtils";

import type { UploadProps } from "element-plus";
import { cpSync } from "fs";
import { fa } from "element-plus/es/locale";

const { proxy } = getCurrentInstance();

const props = withDefaults(
  defineProps<{
    failBoolShow?: boolean; //展示失败数量
    deltetNum?: number; //删除数量
    uploadLoading?: boolean; //上传外边loading
    limit?: number; //限制文件上传最大数量
    multiple?: boolean; //支持多选
    uploadClass?: string; //展示样式class
    path: string;
    params?: Record<string, any>;
    postImage?: string; //  提交的数据名称 ==> 非必传
    defaultShowList?: boolean; //默认展示列表
    fileListShow?: boolean;
    tipShow?: boolean; //提示展示
    tipMsg?: string;
    tipMsgOther?: string;
    maxSize?: number;
    listType?: string;
    imageType?: string; //图片形状
    imageProps?: any; //图片尺寸限制
    accept?: string; //上传类型
    refnameBase?: object;
    toastBool?: boolean; //成功提醒
  }>(),
  {
    failBoolShow: false,
    uploadLoading: false,
    limit: 999,
    multiple: true,
    listType: "text",
    defaultShowList: false,
    tipShow: true, //默认展示
    params: () => ({}),
    imageType: "any", //squire 正方形
    imageProps: { minWidth: 0, maxWidth: 0 },
    fileListShow: true, // 设置默认值
    tipMsg: "传入文件小于20M",
    maxSize: 20,
    toastBool:false
  }
);
console.log(props)
//#region loading
const uploadtestRef = ref(null);
const uploadLoadingObj = reactive({
  //loading加载
  loadingVisable: false,
  beforeUploadNum: 0, //上一次上传全部数量
  allUploading: 20, //全部上传数量
  uplodingNum: 0, //正在上传数量
  currUploadNum: 0, //当前上传数量
  uploadPercentage: 0, //上传百分比
  fileNum: 0 //上传失败
});
const handleClose = () => {
  uploadLoadingObj.loadingVisable = false;
  uploadLoadingObj.uplodingNum = 0;
  uploadLoadingObj.uploadPercentage = 0;
  uploadLoadingObj.fileNum = 0;
  emit("closeLoading");
};
const sumLoading = type => {
  if (!props.uploadLoading) {
    // console.log("不需要打开。。 ");
    return;
  }

  uploadLoadingObj.currUploadNum = uploadLoadingObj.allUploading;
  // uploadLoadingObj.allUploading == uploadLoadingObj.beforeUploadNum
  //   ? uploadLoadingObj.allUploading
  //   : uploadLoadingObj.allUploading - uploadLoadingObj.beforeUploadNum;
  if (uploadLoadingObj.currUploadNum == 1 && uploadLoadingObj.uploadPercentage == 0) {
    uploadLoadingObj.uploadPercentage = 30;
  }
  if (type == "open") {
    uploadLoadingObj.loadingVisable = true; //loading弹框
    console.log(uploadLoadingObj, "videoLoading打开");
    return;
  }

  if (type == "uploading") {
    //正在上传加+ 每次加1
    let num = uploadLoadingObj.uplodingNum;
    uploadLoadingObj.uplodingNum = num + 1;

    uploadLoadingObj.uploadPercentage = (uploadLoadingObj.uplodingNum / uploadLoadingObj.currUploadNum) * 100;

    if (uploadLoadingObj.uploadPercentage == 100) {
      if (props.toastBool) {
      // 吐司提醒
         handleClose();
          ElMessage({
            message: '上传成功',
            type: 'success', 
          })
            emit("closeLoading");
      } else {
        setTimeout(() => {
          // uploadLoadingObj.loadingVisable = false;
          handleClose();
        }, 2000);
      }
    }
  }
};

//#endregion

const picObj = reactive({ width: 0, height: 0 });
const fileList = defineModel<Array<Record<string, any>>>({ default: [] });
console.log(fileList.value, "-----------------------");
const beforeRemoveUpload = (file, files) => {
  // console.log(file, files);
  // console.log("失败请求。。。。");
  var uploadFilesNew = JSON.parse(JSON.stringify(files));
  // console.log(uploadFilesNew);
  fileList.value = uploadFilesNew;
  return false;
};

const beforeAvatarUpload: UploadProps["beforeUpload"] = rawFile => {
  let result = false;
  result = judgeUploadFile(rawFile);

  // if (rawFile.type !== 'image/png' && rawFile.type !== 'image/jpg' && rawFile.type !== 'image/jpeg') {
  //     ElMessage.error('图片仅支持jpg、jpeg、png格式!')
  //     return reject(false);
  //   }

  const isSize = new Promise(function (resolve, reject) {
    if (getJudgeFileType(rawFile) == "image") {
      let _URL = window.URL || window.webkitURL;
      // let img = new Image();
      // img.src = _URL.createObjectURL(rawFile);
      var img = document.createElement("img");
      img.src = _URL.createObjectURL(rawFile);
      // let width = img.width; //获取图片的宽
      // let height = img.height; //获取图片的高
      //   if (props.imageType == "squire") {
      //    console.log(rawFile)
      //   //限制图片为正方形
      //   if (width != height) {
      //     rawFile["tip"]="上传正方形的图"
      //      console.log("上传正方形的图")
      //     ElMessage.error("上传正方形的图");
      //     reject(false);
      //   } else {
      //     let minWidth = props.imageProps.minWidth,
      //       maxWidth = props.imageProps.maxWidth;
      //     if (width >= minWidth && width <= maxWidth) {
      //       // console.log(`正常限制尺寸上传${width}`);
      //       ElMessage.success(`正常限制尺寸上传${width}`);
      //       resolve(true);
      //     } else {
      //        rawFile["tip"] = `图片范围应在${minWidth}~${maxWidth}之内`;
      //       ElMessage.error(`图片范围应在${minWidth}~${maxWidth}之内`);
      //       reject(false);
      //     }
      //   }
      // } else {
      //   resolve(true);
      // }
      img.onload = function () {
        let width = img.width; //获取图片的宽
        let height = img.height; //获取图片的高
        picObj.width = width;
        picObj.height = height;

        resolve(true);
      };
    } else {
      resolve(true);
    }
  }).then(
    () => {
      return rawFile;
    },
    () => {
      // console.log("暂不支持超高像素图片上传");
      return Promise.reject();
    }
  );
  if (!(result && isSize)) {
    handleClose();
  }
  return result && isSize;
};

const judgeUploadFile = rawFile => {
  let result = true;
  const namearr = rawFile.name.split(/\.(?=[^\.]+$)/);
  var len = namearr.length;

  var uploadFilesNew = JSON.parse(JSON.stringify(fileList.value));
  for (let index = 0; index < uploadFilesNew.length; index++) {
    const element = uploadFilesNew[index];
    if (element.uid == rawFile.uid) {
      element["type"] = namearr[len - 1];
    }
  }
  fileList.value = uploadFilesNew;

  if (rawFile.size / 1024 / 1024 > props.maxSize) {
    rawFile["tip"] = "文件大小不能超过" + props.maxSize + "M";
    ElMessage.error(`文件大小不能超过${props.maxSize}M`);
    for (let index = 0; index < uploadFilesNew.length; index++) {
      const element = uploadFilesNew[index];
      if (element.uid == rawFile.uid) {
        element["raw"]["tip"] = "文件大小不能超过" + props.maxSize + "M";
      }
    }

    fileList.value = uploadFilesNew;
    result = false;
  }
  return result;
};

const delfile = (uploadFiles, index) => {
  uploadFiles.splice(index, 1);
};

const getFileData = () => {
  var fileData = [];
  var uploadFiles = JSON.parse(JSON.stringify(fileList.value));

  for (let index = 0; index < uploadFiles.length; index++) {
    const element = uploadFiles[index];
    if (element.status == "success") {
      // console.log(element);
      if (element.response) {
        // var _obj = {};
        // _obj["name"] = element.name;
        // _obj["size"] = element.size;
        // _obj["type"] = element.type;
        // _obj["url"] = element.url;
        //  _obj["file_url"] = element.response?.file_url;
        fileData.push(element.response);
      } else {
        fileData.push(element);
      }
    }
  }

  return fileData;
};

const judgeFileAttr = file => {
  return true;
  let result = true;
  let fileType = getJudgeFileType(file);
  if (fileType == "image") {
    let width = picObj.width,
      height = picObj.height;
    if (props.imageType == "squire") {
      let newFilterArr = fileList.value.filter(fItem => fItem.uid == file.uid);

      //限制图片为正方形
      if (width != height) {
        // rawFile["tip"]="上传正方形的图"
        let minWidth = props.imageProps.minWidth,
          maxWidth = props.imageProps.maxWidth;
        newFilterArr[0].raw["tip"] = proxy.$t("merak.image_range", { minWidth: minWidth, maxWidth: maxWidth });
        // proxy.$t("merak.is_squire");
        // console.log("上传正方形的图");
        // ElMessage.error("上传正方形的图");
        return false;
      } else {
        let minWidth = props.imageProps.minWidth,
          maxWidth = props.imageProps.maxWidth;
        if (width >= minWidth && width <= maxWidth) {
          // console.log(`正常限制尺寸上传${width}`);
          // ElMessage.success(`正常限制尺寸上传${width}`);
          return true;
        } else {
          //  rawFile["tip"] = `图片范围应在${minWidth}~${maxWidth}之内`;
          newFilterArr[0].status = "uploading";
          newFilterArr[0].raw["tip"] = proxy.$t("merak.image_range", { minWidth: minWidth, maxWidth: maxWidth });
          // `图片范围应在${minWidth}~${maxWidth}之内`;
          // console.log(`图片范围应在${minWidth}~${maxWidth}之内`);
          // ElMessage.error(`图片范围应在${minWidth}~${maxWidth}之内`);
          return false;
        }
      }
    }
  }
  return true;
};
const handleRequestInfo = async (options, type) => {
  // console.log("发送请求。。。。");
  const formData = new FormData();
  let file = options.file;
  let fileType = getJudgeFileType(file);
  let width = picObj.width,
    height = picObj.height;
  if (fileType == "image") {
    formData.append("width", width);
    formData.append("height", height);
  }
  // console.log(picObj, "宽高。。。。");

  formData.append(options.filename, options.file);

  if (judgeFileAttr(file)) {
    //判断

    uploadFiles(props.path, props.params, formData, evt => {
      // console.log(evt);
      options.onProgress(evt);
    })
      .then(({ code, data, message }) => {
        sumLoading("uploading");

        if (code == ResultEnum.SUCCESS) {
          // console.log(data);
          // console.log("成功。。。。。。。。。");
          options.onSuccess(data);
        } else {
          uploadLoadingObj.fileNum = uploadLoadingObj.fileNum + 1;
          options.file.tip = message;
          // console.log(options.file.uid);
          // console.log(options.file);

          var uploadFilesNew = JSON.parse(JSON.stringify(fileList.value));

          for (let index = 0; index < uploadFilesNew.length; index++) {
            const element = uploadFilesNew[index];
            if (element.uid == options.file.uid) {
              element.raw["tip"] = message;
            }
          }

          fileList.value = uploadFilesNew;
        }
      })
      .catch(err => {
        uploadLoadingObj.fileNum = uploadLoadingObj.fileNum + 1;
        failMsg("上传失败");
        clear_fail_file();
        sumLoading("uploading");
      });
  } else {
    uploadLoadingObj.fileNum = uploadLoadingObj.fileNum + 1;
    sumLoading("uploading");
  }
};

const clear_fail_file = () => {
  var uploadFiles = JSON.parse(JSON.stringify(fileList.value));
  // console.log("----------------------");
  // console.log(uploadFiles);

  return false;

  for (let index = 0; index < uploadFiles.length; index++) {
    const element = uploadFiles[index];
    console.log(element.status);
    if (element.status == "success" || element.status == "ready") {
    } else {
      uploadFiles.splice(index, 1);
    }
  }
  console.log(uploadFiles);
  fileList.value = uploadFiles;
};
const emit = defineEmits<{
  closeLoading: any;
  changeFile: [value: any];
}>();
const handleChange: UploadProps["onChange"] = (uploadFile, uploadFiles) => {
  //  console.log(props.refnameBase?.baseUploadRef,"uploadChild帆帆帆帆帆帆帆帆帆帆帆帆帆帆")

  const upload_img = props.refnameBase?.baseUploadRef; //document.getElementsByClassName("upload-file");
  if (upload_img) {
    const upload = upload_img.getElementsByTagName("input");
    if (upload && upload.length > 0 && upload[0].files && upload[0].files.length > 0) {
      let uploadNum = upload[0].files.length;

      uploadLoadingObj.allUploading = uploadNum;

      sumLoading("open"); //打开弹窗
    }
  }

  var go_check = 0;

  for (let index = 0; index < uploadFiles.length; index++) {
    const element = uploadFiles[index];
    if (element.response) {
      element["type"] = element.response.type;
      element["url"] = element.response.url;
    } else {
      element["status"] = "uploading";
      if (element.raw?.tip) {
        element["status"] = "fail";
      }

      // var curtype=uploadFile.name;
      // curtype=curtype.split(/\.(?=[^\.]+$)/);
      // var curlen=curtype.length;
      // console.log(curtype)
      // element["type"] = curtype[curlen-1];
      // element["url"] = '';
    }
  }
  // console.log("chufa,,,");
  emit("changeFile", fileList.value);
};

//获取图片属性

const judgePicAttr = pic => {
  return new Promise((resolve, reject) => {
    let reader = new FileReader();
    reader.onload = function (e) {
      var data = e.target.result;
      // 加载图片获取图片真实宽度和高度
      var image = new Image();
      image.onload = function () {
        picObj.width = image.width;
        picObj.height = image.height;
        resolve(picObj);
      };

      image.src = data;
    };
    reader.readAsDataURL(pic);
  });
};

//获取文件类型判断
const getJudgeFileType = file => {
  let name = file.name;
  const fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1).toLowerCase();
  //图片文件类型
  let imageTypes = ["png", "jpg", "jpeg", "gif", "tif", "ibmp", "webp"];
  if (imageTypes.includes(fileSuffix)) {
    return "image";
  }
  //excel文件类型
  let wpsType = ["xls", "xlsx", "xlsm", "pdf", "doc", "docx"];
  if (wpsType.includes(fileSuffix)) {
    return "wps";
  }
  //压缩文件类型
  let zipType = ["zip", "rar", "7z", "tar", "gz"];
  if (zipType.includes(fileSuffix)) {
    return "zip";
  }

  return "file";
};

const readMe = () => {
  let html3 = `图片块儿状配置：
 uploadLoading:true,
  listType: "picture-card",
  uploadClass: "picUpload",
  accept: ".jpg,.jpeg,.png,.gif,.bmp,.webp", //只允许图片上传
  fileListShow: false,
   imageType: props.imageType,
  imageProps: props.imageProps,
  tipShow: false, //提示不展示
  path: props.path`;
  console.log("%c" + html3, "color:OliveDrab;background:yellow");

  let html1 = `图片大块儿配置：
  uploadLoading:true,//外部上传loading
  listType: "picture-card",
  uploadClass: "drag_upload_picture",
  path: '请求路径',
  fileListShow: false,
  tipMsgOther:'框内提示', 
  accept: ".jpg,.jpeg,.png,.gif,.bmp,.webp,.zip"  
  tipShow: false,
  imageType: "squire",//限制等比
  imageProps: { minWidth: 800, maxWidth: 1000 },//判断大小
  params:'外部参数'`;
  console.log("%c" + html1, "color:OliveDrab;background:PaleGreen");

  let html2 = `视频上传：
  uploadLoading:true,//外部上传loading
  listType: "picture-card",
  uploadClass: "drag_upload_picture",
  path: '请求路径',
  fileListShow: false,
  tipMsgOther:'框内提示', 
  accept: ".mp4,.zip",
  tipShow: false, 
  params:'外部参数'`;

  console.log("%c" + html2, "color:red;background:yellow");
};

const uploadLoadingReload = event => {
  event.stopPropagation();
  event.preventDefault();
  const files = event.dataTransfer.files;
  uploadLoadingObj.allUploading = files.length;
  sumLoading("open"); //打开弹窗
};

onMounted(async () => {
  await nextTick();
  const upload_img = props.refnameBase?.baseUploadRef;
  console.log(upload_img);
  if (upload_img) {
    const upload = upload_img.getElementsByClassName("el-upload-dragger");
    console.log(upload);
    if (upload && upload.length > 0) {
      upload[0].removeEventListener("drop", uploadLoadingReload);
      upload[0].addEventListener("drop", function (event) {
        uploadLoadingReload(event);
      });
    }
  }
});

onUnmounted(() => {});

defineExpose({
  readMe,
  getFileData,
  getJudgeFileType, //判断类型
  refName: computed(() => uploadtestRef.value)
});
</script>
<style lang="scss" scoped>
@import url("./index.scss");
</style>
<style scoped>
/* :deep(.el-upload-list) {
  display: none;
} */

:deep(.el-button--danger.is-link, .el-button--danger.is-plain, .el-button--danger.is-text) {
  text-align: left;
  align-items: start;
  justify-content: left;
}

.file_ever {
  position: relative;
}

.progress_div {
  position: absolute;
  bottom: 27px;
  left: 0;
  width: 100%;
}

.upload_table {
  position: relative;

  .th_tr {
    margin-top: 20px;

    display: flex;
    background-color: #f5f8fa;
    width: 100%;

    .upload_th {
      height: 40px;
      padding: 0 16px;
      line-height: 40px;
      color: #646567;
      font-size: 12px;
    }
  }

  :deep(.el-upload-list) {
    padding-top: 50px;
  }
}

.avatar-uploader .avatar {
  width: 60px;
  height: 60px;
  display: block;
}

.file_ever {
  display: flex;

  .td {
    /* height: 40px; */
    padding: 0 16px;
    line-height: 40px;
    color: #646567;
    font-size: 12px;
  }
  .td.icon_show {
    i {
      font-size: 14px;
      position: relative;
      top: 2px;
      margin-right: 4px;
    }

    .success {
      color: #28ae60;
    }
    .error {
      color: #e74c3d;
    }
  }
}
</style>

<style>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 60px;
  height: 60px;
  text-align: center;
}
</style>
